package com.gopay.remote.acps.service;

import java.util.List;
import java.util.Map;

import com.gopay.common.constants.dic.SchemaCode;
import com.gopay.common.domain.acps.AcctMastField;
import com.gopay.common.domain.acps.AcctMastType;
import com.gopay.common.domain.acps.AcctProd;
import com.gopay.common.domain.acps.AcpsAcctOperatLogs;
import com.gopay.common.domain.acps.AcpsFrezTransDtl;
import com.gopay.common.domain.acps.CurrencyCode;
import com.gopay.common.domain.acps.FreezeMessage;
import com.gopay.common.domain.acps.FrezInfoBean;
import com.gopay.common.domain.acps.FrezVerifyRank;
import com.gopay.common.domain.acps.TranInfoBean;
import com.gopay.common.domain.acps.TranResult;
import com.gopay.common.domain.acps.VerifyResult;
import com.gopay.common.domain.acps.model.AcctMastBean;

/**
 * 账务接口
 * 
 * @author zhanglei
 * @version 1.0 2012-8-3
 */
public interface AcctTransRemoteService {
    /**
     * 测试web service 是否可用
     * 
     * @return 总是返回true
     */
    boolean isAvailable();

    /**
     * 根据custId查询虚拟卡账户
     * 
     * @param custId
     * @return
     */
    List<AcctMastBean> getAccounts(String custId);

    /**
     * 根据custId查询虚拟卡账户 支持分页
     * 
     * @param custId
     * @return
     */
    List<AcctMastBean> getVisualAccounts(String custId, int pageIndex, int pageSize);

    /**
     * 根据custId查询虚拟卡账户数量
     * 
     * @param custId
     * @return
     */
    int accountsCount(String custId);

    /**
     * 根据帐号（虚拟卡号/AcctId）查询账户信息；
     * 
     * 如果数据库找不到记录，返回null;
     * 
     * @param acctId
     * @return
     */
    AcctMastBean getAccount(String acctId);

    /**
     * 验证acctId的密码是否为unverifiedPassword。
     * 
     * <pre>
     * 1.如果账户已经是密码锁定状态，返回TranResult.success=false;
     * 2.如果验证通过，返回TranResult.success=true;
     * 3.如果验证未通过，且当日连续错误次数<3，则返回TranResult.success=false;
     * 4.如果验证未通过，且当日连续错误次数>=3，则返回TranResult.success=false，同时将账户置为密码当日锁定状态。
     * </pre>
     * 
     * @param unverifiedPassword
     *            - 用户输入的密码明文！
     * 
     */
    TranResult verifyPassword(String acctId, String unverifiedPassword);

    /**
     * 执行账务
     */
    TranResult doTrans(TranInfoBean tran);

    /**
     * 执行冻结
     * 
     * !!!已作废，请使用doFrezTrans接口
     */
    @Deprecated
    TranResult doFreeze(FreezeMessage message);

    /**
     * 执行解冻
     * 
     * !!!已作废，请使用doFrezTrans接口
     */
    @Deprecated
    TranResult doUnfreeze(String tranId);

    /**
     * 执行冻结/解冻 审核
     * 
     * !!!已作废，请使用doFrezTrans接口
     * 
     * @param tranId
     *            - 冻结/解冻 交易号
     * @param result
     *            - 审核结果
     * @param vrfUserId
     *            - 审核员的userId
     * @param rank
     *            - 审核级别
     */
    @Deprecated
    TranResult doFrezVerify(String tranId, VerifyResult result, String vrfUserId, FrezVerifyRank rank);

    /**
     * 根据acctId查询冻结交易明细 支持分页
     * 
     * !!!已作废，请使用doFrezTrans接口
     * 
     * @param acctId
     * @param pageIndex
     * @param pageSize
     * @return
     */
    @Deprecated
    List<AcpsFrezTransDtl> getFrezTransDtlByAcctId(String acctId, int pageIndex, int pageSize);

    /**
     * 记录数
     * 
     * !!!已作废，请使用doFrezTrans接口
     * 
     * @param acctId
     * @return
     */
    @Deprecated
    Integer getFrezTransDtlCountByAcctId(String acctId);

    /**
     * 更新 账户信息主表
     * 
     * <pre>
     * 调用示例：
     * Map&lt;AcctMastField, String&gt; vs = new HashMap&lt;AcctMastField, String&gt;();
     * vs.put(AcctMastField.PAY_PWD, "1111aaaa");
     * vs.put(AcctMastField.ACCT_NAME, &quot;张三&quot;);
     * TranResult r = doTransService.updateAcctMast(&quot;0000000009220200001&quot;, vs);
     * </pre>
     * 
     * @param acctId
     * @param values
     * @return
     */
    TranResult updateAcctMast(String acctId, Map<AcctMastField, String> values);

    /**
     * 更新 账户信息锁定状态并记录操作日志
     *
     * <pre>
     * 调用示例：
     * Map&lt;AcctMastField, String&gt; vs = new HashMap&lt;AcctMastField, String&gt;();
     * vs.put(AcctMastField.PAY_PWD, "1111aaaa");
     * vs.put(AcctMastField.ACCT_NAME, &quot;张三&quot;);
     * TranResult r = doTransService.updateAcctMast(&quot;0000000009220200001&quot;, vs);
     * </pre>
     *
     * @param acctId
     * @param values
     * @return
     */
    TranResult updateAcctStatus(String acctId, Map<AcctMastField, String> values, AcpsAcctOperatLogs acpsAcctOperatLogs);

    /**
     * 更新 账户信息主表
     * 
     * <pre>
     * 调用示例：
     * Map&lt;AcctMastField, String&gt; vs = new HashMap&lt;AcctMastField, String&gt;();
     * vs.put(AcctMastField.PAY_PWD, "1111aaaa");
     * vs.put(AcctMastField.ACCT_NAME, &quot;张三&quot;);
     * TranResult r = doTransService.updateAcctMasts(&quot;0000003358&quot;, vs);
     * </pre>
     * 
     */
    TranResult updateAcctMasts(String custId, Map<AcctMastField, String> values);

    /**
     * 根据账户产品查询所有账户
     */
    List<AcctMastBean> findAccount(AcctProd acctProd, int pageIndex, int pageSize);

    /**
     * 冻结/解冻交易。
     * 
     * 注：gopayOrderId，packageId暂时还没字段保存，故还没有用到。
     */
    TranResult doFrezTrans(FrezInfoBean bean);

    /**
     * 为所有表清零每日限额字段，如密码重试次数、日内提现金额等
     */
    TranResult clearDailyLimit();

    /**
     * 创建一个账户(其他字段为默认值)
     */
    TranResult createAccount(AcctMastType type, String custId, String acctName, SchemaCode schemaCode,
            AcctProd acctProd, CurrencyCode cur, String remark);

    /**
     * 检查是否存在账务记录
     * @param gopayOrderId
     * @return
     */
    public int checkAcpsAcctTransDtl(String gopayOrderId);
}
